﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

using cszmcaux;
using Newtonsoft.Json;


namespace 三轴机
{
    public partial class Form1 : Form
    {

        //轴0是横向移动y，轴1是竖向移动x，轴2是Z轴


        public IntPtr g_handle;                         //链接返回的句柄，可以作为卡号

        public int[] AxisList = { 0, 1, 2 };            //轴列表



        public int nAxis = 3;                           //轴数量

        public int dir = 1;                             //运动方向

        public int Timing_time = 500;                   //定时检测时间 ms

        public int InputNum = 11;                       //输入口数量

        public int[] INputs = new int[20];              //输入口列表

        public uint[] INput_Station = new uint[50];     //输入口状态

        public int OutputNum = 15;                      //输出口数量

        public int[] Outputs = new int[20];             //输出口列表

        public uint[] Output_Station = new uint[50];     //输出口状态

        public float Crawle_Speed;                      //复位爬行速度

        public int ResetCrawle_time = 10;               //设置回零返找等待时间(ms)

        public int[] AxisSportStation = new int[10];    //轴运动状态（0 –没有完成，-1-运动完成）

        public bool[] Reset_result = new bool[5];       //复位结果

        public int[] Key_INput = new int[50];           //字典输入键

        public int[] Key_OUTput = new int[50];          //字典输出键

        public int move_modle = 0;                     //运动模动-插补运动用

        float[] position = new float[3];               //当前坐标位置列表



        int[] Motion_state = { };
        float[] Current_pos = { };


        Dictionary<int, System.Windows.Forms.Button> Dic_Io = new Dictionary<int, System.Windows.Forms.Button>();  //字典

        public Form1()
        {
            InitializeComponent();

            Dictionary_add();
            Initialization_Axix(nAxis);                 //轴初始化

            Set_origin_sinal();                         //原点设置

            IO_detection(InputNum, OutputNum);          //IO检测亮灯



        }

        #region  参数保存

        //新建一个类保存控件的名字和值
        public class ControlValue
        {
            public string Name { get; set; }

            public string Value { get; set; }
        }

        //新建一个字典方法

        private Dictionary<string, string> GetAllControlValues(Control parent)
        {
            Dictionary<string, string> ControlValues = new Dictionary<string, string>();

            //历遍所有控件
            foreach (Control control in parent.Controls)
            {
                if (control is System.Windows.Forms.TextBox textBox) //文本框
                {
                    ControlValues.Add(textBox.Name, textBox.Text);
                }
                else if (control is NumericUpDown numericUpDown) //数字框
                {
                    ControlValues.Add(numericUpDown.Name, Convert.ToString(numericUpDown.Value));
                }
                else if (control is CheckBox checkBox)  //checkbox
                {
                    ControlValues.Add(checkBox.Name, checkBox.Text);
                }
                else if (control is Label label) //字符
                {
                    ControlValues.Add(label.Name, label.Text);
                }
                else if(control is TrackBar trackBar)
                {
                    ControlValues.Add(trackBar.Name, Convert.ToString( trackBar.Value));
                }
                else if (control.HasChildren)  //子控件
                {
                    var ChildreControlValue = GetAllControlValues(control);
                    foreach (var kpv in ChildreControlValue)
                    {
                        ControlValues.Add(kpv.Key, kpv.Value);
                    }
                }
            }
            return ControlValues;
        }

        //上面得到的控件值保存到文件中
        private void  SaveControlDate(Dictionary<string,string>controlValues)
        {
            //1.序列化字典：使用 JsonSerializer.Serialize 方法将字典 controlValues 序列化为 JSON 字符串。
            string JsonString = JsonConvert.SerializeObject(controlValues, Formatting.Indented);
            File.WriteAllText("controlValues.json", JsonString);
        }

        //保存到文件中的控件值读取出来
        private void LoadControlDate( Control parent)
        {
            //1.检查文件是否存在：使用 File.Exists 方法检查文件 controlValues.json 是否存在。
            //如果文件不存在，则显示提示并返回。
            if(!File.Exists("controlValues.json"))
            {
                MessageBox.Show("File nu found!");
                return;
            }

            string Jsonstring = File.ReadAllText("controlValues.json");

           
            //反序列化并赋值给字典
            Dictionary<string, string> controlValues = JsonConvert.DeserializeObject<Dictionary<string, string>>(Jsonstring); 

            foreach ( Control control  in parent.Controls )
            {
                if(control is TextBox textBox && controlValues.ContainsKey(textBox.Name))
                {
                    textBox.Text = controlValues[textBox.Name];
                }
                else if (control is NumericUpDown numericUpDown && controlValues.ContainsKey(numericUpDown.Name))
                {
                    numericUpDown.Value = Convert.ToInt32( controlValues[numericUpDown.Name]);
                }
                else if (control is ComboBox comboBox && controlValues.ContainsKey(comboBox.Name))
                {
                    comboBox.Text = controlValues[comboBox.Name];
                }
                else if (control is Label label && controlValues.ContainsKey(label.Name))
                {
                    label.Text = controlValues[label.Name];
                }
                else if(control.HasChildren)
                {
                    LoadControlDate(control);
                }
            }


        }

        //保存按钮
        private void btn_save_Click(object sender, EventArgs e)
        {
            //btn_save.BackColor = Color.Green;
            try
            {
                var controlValues = GetAllControlValues(this);
                SaveControlDate(controlValues);
                MessageBox.Show("保存成功");
                //btn_save.BackColor = Color.Gainsboro;
            }
            catch (Exception ex)
            {
                MessageBox.Show("保存失败: " + ex.Message);
            }
        }

        //下载按钮
        private void btn_load_Click(object sender, EventArgs e)
        {
            //btn_load.BackColor = Color.Green;
            
            try
            {
                LoadControlDate(this);
                MessageBox.Show("下载成功");
                //btn_load.BackColor = Color.Gainsboro;
            }
            catch (Exception ex)
            {
                MessageBox.Show("下载失败: " + ex.Message);
            }
        }
        #endregion


        #region 轴初始化
        /// <summary>
        /// 轴初始化
        /// </summary>
        public void Initialization_Axix(int Axis_Num)
        {
            for (int naixs = 0; naixs < Axis_Num; naixs++)
            {
                zmcaux.ZAux_Direct_SetAtype(g_handle, naixs, 1);                                         //轴类型(脉冲型)
                zmcaux.ZAux_Direct_SetAccel(g_handle, naixs, Convert.ToSingle(WorkAxis_Accel.Value));         //加速度
                zmcaux.ZAux_Direct_SetDecel(g_handle, naixs, Convert.ToSingle(WorkAxis_decel.Value));         //减速度
                zmcaux.ZAux_Direct_SetUnits(g_handle, naixs, Convert.ToSingle(cBox_units.SelectedItem)); //脉冲当量 一 脉冲为单位
                zmcaux.ZAux_Direct_SetSpeed(g_handle, naixs, Convert.ToSingle(WorkAxis_Speed.Value));        //速度
                zmcaux.ZAux_Direct_SetLspeed(g_handle, nAxis, Convert.ToSingle(WorkAxis_ang1.Value));         //起始速度
                zmcaux.ZAux_Direct_SetDecelAngle(g_handle, naixs, Convert.ToSingle(WorkAxis_ang1.Value));     //拐角起始减速角度
                zmcaux.ZAux_Direct_SetStopAngle(g_handle, naixs, Convert.ToSingle(WorkAxis_ang2.Value));      //拐角停止减速角度
                zmcaux.ZAux_Direct_SetFullSpRadius(g_handle, naixs, Convert.ToSingle(WorkAxis_radio.Value));  //小圆限速半径
                zmcaux.ZAux_Direct_SetZsmooth(g_handle, naixs, Convert.ToSingle(WorkAxis_radio.Value));       //倒角限速半径
                zmcaux.ZAux_Direct_SetSramp(g_handle, nAxis, Convert.ToSingle(WorkAxis_Speed.Value));        //S曲线加减速度

            }


            zmcaux.ZAux_Direct_Base(g_handle, 3, AxisList);  //运动轴列表
            //插补运动使用的是主轴参数，及BASE的第一个轴


        }
        #endregion





        #region  定时检测是否通讯，IO
        /// <summary>
        /// //定时检测是否通讯，IO
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>


        #region  定时检测1-通讯检测

        private void timer1_Tick(object sender, EventArgs e)
        {
            if (g_handle != (IntPtr)0)
            {
                timer1_Com.Interval = Timing_time;

            }


            else
            {
                MessageBox.Show("控制器链接失败，请检测IP地址!", "警告!");
            }


        }

        /// <summary>
        /// 连接键
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button1_connect_Click(object sender, EventArgs e)
        {

            zmcaux.ZAux_OpenEth(textBox1.Text, out g_handle);  //以太网方式连接

            if (g_handle != (IntPtr)0)  //不为0连接成功
            {

                MessageBox.Show("连接成功");
                label22.Text = "/通讯成功/";
                label22.ForeColor = Color.Green;

                timer1_Com.Start();
                timer2_IO.Start();
            }
            else
            {
                MessageBox.Show("通讯失败，请重试");
                label22.Text = "/未通讯/";
                label22.ForeColor = Color.Red;
            }
        }



        /// <summary>
        /// 窗口关闭释放资源，关闭链接，释放HANDLE
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            timer1_Com.Enabled = false;
            zmcaux.ZAux_Close(g_handle);  //释放资源
            g_handle = (IntPtr)0; //关闭连接

        }
        #endregion

        #region  定时检测1-IO检测

        private void timer2_IO_Tick(object sender, EventArgs e)
        {
            IO_detection(InputNum, OutputNum);
            trackbar_Value_Update();//滑块最大值数值更新
            pos_Upate();            //位置监控
            GetAxisStatusToLabel(); //检测速度
            if (position[0] == 0 && position[1] == 0)
            {
                button_origin.BackColor = Color.Gainsboro;

                button_origin.Text = "复位";
            }
            else { }
        }


        public void IO_detection(int INputNumber, int OutNumber)  //IO检测
        {

            for (int i = 0; i <= INputNumber; i++)
            {
                zmcaux.ZAux_Direct_GetIn(g_handle, i, ref INput_Station[i]);

                if (INput_Station[i] == 1)
                {
                    Dic_Io[Key_INput[i]].BackColor = Color.Green;
                }
                else
                {
                    Dic_Io[Key_INput[i]].BackColor = Color.Gainsboro;
                }
            }
            for (int i = 0; i <= OutNumber; i++)
            {
                zmcaux.ZAux_Direct_GetOp(g_handle, i, ref Output_Station[i]);
                if (Output_Station[i] == 1)
                {
                    Dic_Io[Key_OUTput[i]].BackColor = Color.Green;
                }
                else
                {
                    Dic_Io[Key_OUTput[i]].BackColor = Color.Gainsboro;
                }
            }


        }
        // /*
        public void Dictionary_add() //添加输入/输出的键值对
        {
            for (int i = 0; i < 20; i++)
            {
                Key_INput[i] = i;
                Key_OUTput[i] = i + 20;
            }
            //添加输入的键值对
            Dic_Io.Add(Key_INput[0], btn_in0);
            Dic_Io.Add(Key_INput[1], btn_in1);
            Dic_Io.Add(Key_INput[2], btn_in2);
            Dic_Io.Add(Key_INput[3], btn_in3);
            Dic_Io.Add(Key_INput[4], btn_in4);
            Dic_Io.Add(Key_INput[5], btn_in5);
            Dic_Io.Add(Key_INput[6], btn_in6);
            Dic_Io.Add(Key_INput[7], btn_in7);
            Dic_Io.Add(Key_INput[8], btn_in8);
            Dic_Io.Add(Key_INput[9], btn_in9);
            Dic_Io.Add(Key_INput[10], btn_in10);
            Dic_Io.Add(Key_INput[11], btn_in11);

            //添加输出的键值对
            Dic_Io.Add(Key_OUTput[0], btn_out0);
            Dic_Io.Add(Key_OUTput[1], btn_out1);
            Dic_Io.Add(Key_OUTput[2], btn_out2);
            Dic_Io.Add(Key_OUTput[3], btn_out3);
            Dic_Io.Add(Key_OUTput[4], btn_out4);
            Dic_Io.Add(Key_OUTput[5], btn_out5);
            Dic_Io.Add(Key_OUTput[6], btn_out6);
            Dic_Io.Add(Key_OUTput[7], btn_out7);
            Dic_Io.Add(Key_OUTput[8], btn_out8);
            Dic_Io.Add(Key_OUTput[9], btn_out9);
            Dic_Io.Add(Key_OUTput[10], btn_out10);
            Dic_Io.Add(Key_OUTput[11], btn_out11);
            Dic_Io.Add(Key_OUTput[12], btn_out12);
            Dic_Io.Add(Key_OUTput[13], btn_out13);
            Dic_Io.Add(Key_OUTput[14], btn_out14);
            Dic_Io.Add(Key_OUTput[15], btn_out15);

        }
        // */
        #endregion

        #endregion


        #region  手动速度数值显示
        /// <summary>
        /// 手动速度数值显示
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void trackBar1_Scroll(object sender, EventArgs e)
        {
            txtBox_HandSpeed.Text = trackBar1.Value.ToString();
            for (int i = 0; i < 3; i++)
            {
                zmcaux.ZAux_Direct_SetSpeed(g_handle, AxisList[i], Convert.ToSingle(trackBar1.Value));
            }

        }
        private void trackBar1_ValueChanged(object sender, EventArgs e) //更改手动运动速度框
        {
            txtBox_HandSpeed.Text = trackBar1.Value.ToString();
            for (int i = 0; i < 3; i++)
            {
                zmcaux.ZAux_Direct_SetSpeed(g_handle, AxisList[i], Convert.ToSingle(txtBox_HandSpeed.Text));
            }
        }

        private void num_MaxSped_ValueChanged(object sender, EventArgs e)
        {
            //滑块数值刷新
            trackbar_Value_Update();
        }

        public void trackbar_Value_Update()
        {
            //滑块数值刷新
            trackBar1.Maximum = Convert.ToInt32(num_HandMaxSped.Value);
            trackBar1.Minimum = 0;
        }
        #endregion


        #region ↑↓←→ JOG运动


        #region  向↑运动
        /// <summary>
        /// 向↑运动
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>

        private void button_Up_MouseDown(object sender, MouseEventArgs e)
        {

            button2_Up.BackColor = Color.Green;
            Motion_move_MouseDown(1, 1);  //填入轴号和方向
        }

        private void button_Up_MouseUp(object sender, MouseEventArgs e)
        {
            button2_Up.BackColor = Color.Gainsboro;
            Motion_move_MouseUP(1);
        }

        #endregion


        #region  向↓运动

        /// <summary>
        /// ↓
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>

        private void button_down_MouseDown(object sender, MouseEventArgs e)  //Y-运动
        {
            button_down.BackColor = Color.Green;
            Motion_move_MouseDown(1, -1);
        }

        private void button_down_MouseUp(object sender, MouseEventArgs e)
        {
            button_down.BackColor = Color.Gainsboro;
            Motion_move_MouseUP(1);
        }



        #endregion


        #region 向←运动
        /// <summary>
        /// ←
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>




        private void button_left_MouseDown(object sender, MouseEventArgs e)//←
        {
            button_left.BackColor = Color.Green;
            Motion_move_MouseDown(0, 1);
        }

        private void button_left_MouseUp(object sender, MouseEventArgs e)
        {
            button_left.BackColor = Color.Gainsboro;
            Motion_move_MouseUP(0);
        }

        #endregion


        #region  向→运动
        private void button_right_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Right)
            {
                button_right.BackColor = Color.Green;
                Motion_move_MouseDown(0, -1);
            }
        }


        private void button_right_MouseDown(object sender, MouseEventArgs e)
        {
            button_right.BackColor = Color.Green;
            Motion_move_MouseDown(0, -1);
        }
        private void button_right_MouseUp(object sender, MouseEventArgs e)
        {
            button_right.BackColor = Color.Gainsboro;
            Motion_move_MouseUP(0);
        }



        #endregion


        #region  向z↑运动
        private void btn_ZUp_MouseDown(object sender, MouseEventArgs e)
        {
            btn_ZUp.BackColor = Color.Green;
            Motion_move_MouseDown(2, 1);
        }

        private void btn_ZUp_MouseUp(object sender, MouseEventArgs e)
        {
            btn_ZUp.BackColor = Color.Gainsboro;
            Motion_move_MouseUP(2);

        }
        #endregion


        #region  向z↓运动
        private void btn_ZDown_MouseDown(object sender, MouseEventArgs e)
        {
            btn_ZDown.BackColor = Color.Green;
            Motion_move_MouseDown(2, -1);
        }

        private void btn_ZDown_MouseUp(object sender, MouseEventArgs e)
        {
            btn_ZDown.BackColor = Color.Gainsboro;
            Motion_move_MouseUP(2);
        }

        #endregion


        #region  键盘控制运动
        private void btn_HandControl_Click(object sender, EventArgs e)  //按下键盘控制时
        {
            if (btn_HandControl.BackColor == Color.Gainsboro)
            {
                btn_HandControl.BackColor = Color.Green;
                btn_HandControl.Text = "键盘控制中";
            }
            else if (btn_HandControl.BackColor == Color.Green)
            {
                btn_HandControl.BackColor = Color.Gainsboro;
                btn_HandControl.Text = "键盘控制";
            }

        }

        private void btn_HandControl_KeyDown(object sender, KeyEventArgs e) //按下键盘控制后按下键盘指定键进行运动
        {
            if (btn_HandControl.Text == "键盘控制中")
            {
                if (e.KeyCode == Keys.W && e.KeyCode != Keys.S)                   //↑
                {

                    button2_Up.BackColor = Color.Green;
                    Motion_move_MouseDown(1, 1);  //填入轴号和方向
                }
                if (e.KeyCode == Keys.S && e.KeyCode != Keys.A)                    //↓
                {

                    button_down.BackColor = Color.Green;
                    Motion_move_MouseDown(1, -1);

                }
                if (e.KeyCode == Keys.A && e.KeyCode != Keys.D)                    //←
                {

                    button_left.BackColor = Color.Green;
                    Motion_move_MouseDown(0, 1);
                }
                if (e.KeyCode == Keys.D && e.KeyCode != Keys.A)                   //→
                {

                    button_right.BackColor = Color.Green;
                    Motion_move_MouseDown(0, -1);
                }
                if (e.KeyCode == Keys.PageUp && e.KeyCode != Keys.Q)
                {

                    btn_ZUp.BackColor = Color.Green;
                    Motion_move_MouseDown(2, 1);
                }
                if (e.KeyCode == Keys.PageDown && e.KeyCode != Keys.E)
                {

                    btn_ZDown.BackColor = Color.Green;
                    Motion_move_MouseDown(2, -1);
                }

            }

        }

        private void btn_HandControl_KeyUp(object sender, KeyEventArgs e)//按下键盘控制后松开键盘指定键停止运动
        {
            if (e.KeyCode == Keys.W)           //↑
            {
                button2_Up.BackColor = Color.Gainsboro;
                Motion_move_MouseUP(1);
            }
            if (e.KeyCode == Keys.S)
            {
                button_down.BackColor = Color.Gainsboro;
                Motion_move_MouseUP(1);
            }
            if (e.KeyCode == Keys.A)
            {
                button_left.BackColor = Color.Gainsboro;
                Motion_move_MouseUP(0);
            }
            if (e.KeyCode == Keys.D)
            {
                button_right.BackColor = Color.Gainsboro;
                Motion_move_MouseUP(0);
            }
            if (e.KeyCode == Keys.PageUp)
            {

                btn_ZUp.BackColor = Color.Gainsboro;
                Motion_move_MouseUP(2);
            }
            if (e.KeyCode == Keys.PageDown)
            {

                btn_ZDown.BackColor = Color.Gainsboro;
                Motion_move_MouseUP(2);
            }
        }

        #endregion

        #endregion


        #region  手动控制方法

        public void Motion_move_MouseDown(int axle, int this_dir)   //按下轴连续运动与寸动
        {
            if (g_handle != (IntPtr)0)
            {
                int this_axis = AxisList[axle];         //轴号

                if (rButton1_Continuous_motion.Checked)  //选择连续运动
                {

                    zmcaux.ZAux_Direct_SetJogSpeed(g_handle, this_axis, trackBar1.Value);//JOG速度

                    zmcaux.ZAux_Direct_Single_Vmove(g_handle, this_axis, this_dir);
                }
                else if (rButton2_inch_motion.Checked)     //选择寸动
                {
                    zmcaux.ZAux_Direct_Single_Move(g_handle, this_axis, this_dir * Convert.ToSingle(txt_inch_distance.SelectedItem));

                }
                else { }

            }
            else
            {
                MessageBox.Show("通讯失败，请重试", "提示！");
            }
        }

        public void Motion_move_MouseUP(int axle)
        {
            int this_axis = AxisList[axle];
            if (rButton1_Continuous_motion.Checked)
            {
                zmcaux.ZAux_Direct_Single_Cancel(g_handle, this_axis, 3);
            }
            else { }
        } //松开停止

        #endregion

        //复位功能
        #region  //设置原点传感器
        /// <summary>
        /// 设置原点传感器 ZMC 控制器缺省为 OFF 有效，常开信号用 INVERT_IN 反转电平；
        /// </summary>
        public void Set_origin_sinal()
        {

            zmcaux.ZAux_Direct_SetDatumIn(g_handle, AxisList[0], 0);                                     //轴号0原点信号为Input_0  Y
            zmcaux.ZAux_Direct_SetInvertIn(g_handle, 0, 0);                                              //设置原点信号表示低电平有效    0-常开 1-常闭


            zmcaux.ZAux_Direct_SetDatumIn(g_handle, AxisList[1], 1);                                      //轴号1原点信号为Input_1       X
            zmcaux.ZAux_Direct_SetInvertIn(g_handle, 1, 0);                                               //设置原点信号表示低电平有效


            zmcaux.ZAux_Direct_SetDatumIn(g_handle, AxisList[2], 2);                                     //轴号2原点信号为Input_2           Z
            zmcaux.ZAux_Direct_SetInvertIn(g_handle, 2, 0);                                              //设置原点信号表示低电平有效

            for (int i = 0; i < 3; i++)
            {
                zmcaux.ZAux_Direct_SetHomeWait(g_handle, AxisList[i], ResetCrawle_time);
            }





        }
        #endregion

        #region //复位按键
        /// <summary>
        /// //复位按键
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button_origin_Click(object sender, EventArgs e)   //复位按键
        {
            if (g_handle != (IntPtr)0)  //不为0连接成功
            {
                button_origin.BackColor = Color.Green;
                button_origin.Text = "复位中";

                //设置原点
                Set_origin_sinal();

                for (int i = 0; i < 3; i++)
                {
                    zmcaux.ZAux_Direct_SetAccel(g_handle, AxisList[i], 1000); //加速度
                    zmcaux.ZAux_Direct_SetDecel(g_handle, AxisList[i], 2000); //减速度
                }

                zmcaux.ZAux_Direct_SetSpeed(g_handle, AxisList[1], Convert.ToSingle(num_XresetV.Value));
                zmcaux.ZAux_Direct_SetSpeed(g_handle, AxisList[0], Convert.ToSingle(num_YresetV.Value));
                zmcaux.ZAux_Direct_SetSpeed(g_handle, AxisList[2], Convert.ToSingle(num_ZresetV.Value));

                zmcaux.ZAux_Direct_SetCreep(g_handle, AxisList[0], Convert.ToSingle(num_XresetV.Value / 2));     //设置 X轴 的复位爬行速度
                zmcaux.ZAux_Direct_SetCreep(g_handle, AxisList[1], Convert.ToSingle(num_YresetV.Value / 2));     //设置 X轴 的复位爬行速度
                zmcaux.ZAux_Direct_SetCreep(g_handle, AxisList[2], Convert.ToSingle(num_ZresetV.Value / 2));     //设置 X轴 的复位爬行速度

                //新建一个Task
                Task t1 = new Task(() =>
                {

                    Thread.Sleep(10000);  //延时10s等待Z轴复位


                });

                //启动Task
                //     t1.Start();


                zmcaux.ZAux_Direct_Single_Datum(g_handle, AxisList[2], 3);             //Z轴控制器方式回零

                //    t1.Wait();//阻塞住，等待延时完毕往下执行


                if (position[2] == 0)  //Z轴回零完成下一步
                {

                    zmcaux.ZAux_Direct_Single_Datum(g_handle, AxisList[0], 4);            //Y轴控制器方式回零

                    zmcaux.ZAux_Direct_Single_Datum(g_handle, AxisList[1], 4);            //X轴控制器方式回零


                    //      t1.Start();                //延时10s,读xy轴是否复位完成




                    if (position[0] == 0 && position[1] == 0)
                    {
                        MessageBox.Show("复位完成");

                        //         for (int i = 0; i < 3; i++) { zmcaux.ZAux_Direct_SetDpos(g_handle, AxisList[i], 0); }

                        button_origin.BackColor = Color.Gainsboro;

                        button_origin.Text = "复位";
                    }
                    else { }

                    /*
                    else if (AxisSportStation[0] != 0)
                    {
                        MessageBox.Show("Y轴复位失败");
                        button_origin.BackColor = Color.Gainsboro;
                        button_origin.Text = "复位";
                    }
                    else
                    {
                        MessageBox.Show("X轴复位失败");
                        button_origin.BackColor = Color.Gainsboro;
                        button_origin.Text = "复位";
                    }
                }
                else
                {
                    MessageBox.Show("Z轴复位失败");
                    button_origin.BackColor = Color.Gainsboro;
                    button_origin.Text = "复位";
                }

            }*/
                }
                else
                {

                    MessageBox.Show("通讯失败，请重试");

                }
            }
        }
        #endregion




        #region //轴参数更新——点击电机保存设置
        private void btn_SetAxle_MouseDown(object sender, MouseEventArgs e)   //轴参数更新——点击电机保存设置
        {
            btn_SetAxisParameter.BackColor = Color.Green;

            Initialization_Axix(nAxis);                 //轴初始化
        }

        private void btn_SetAxle_MouseUp(object sender, MouseEventArgs e)
        {
            btn_SetAxisParameter.BackColor = Color.Gainsboro;
        }
        #endregion





        private void btn_MoveTo_Click(object sender, EventArgs e)  //移动到
        {


        }



        private void Axis_speed_ValueChanged_1(object sender, EventArgs e)  //速度改变
        {
            zmcaux.ZAux_Direct_SetSpeed(g_handle, 0, Convert.ToSingle(WorkAxis_Speed.Value));
        }








        //发送运动
        public void RunMove()
        {
            float[] LineMovePoslist = { Convert.ToSingle(LinePos_X1MidPoint.Value), Convert.ToSingle(LinePos_Y1MidPoint.Value), Convert.ToSingle(LinePos_Z0Height.Value) };
            float[] CircleMoveMidlist = { Convert.ToSingle(CirclePos_X1MidPoint.Value), Convert.ToSingle(CirclePos_Y1MidPoint.Value), Convert.ToSingle(CirclePos_X2EndPoint.Value), Convert.ToSingle(CirclePos_Y2EndPoint.Value), Convert.ToSingle(CirclePos_Z0Height.Value) };

            switch (move_modle)
            {
                case 1:                             //XYZ直线                !!! Z轴是否会提前下降？
                    zmcaux.ZAux_Direct_MoveAbs(g_handle, 3, AxisList, LineMovePoslist);


                    break;
                case 2:                             //XYZ圆弧                !!! Z轴是否会提前下降？
                                                    //绝对位置圆弧插补圆弧插补运动，轴列表中第一轴和第二轴进行圆弧插补，绝对移动方式。
                                                    //fmid1 第一个轴中间点，绝对位置
                                                    //fmid2 第二个轴中间点，绝对位置。
                                                    //fend1 第一个轴结束点，绝对位置。
                                                    //fend2 第二个轴结束点，绝对位置。
                    zmcaux.ZAux_Direct_MoveCirc2Abs(g_handle, 3, AxisList, CircleMoveMidlist[0], CircleMoveMidlist[1], CircleMoveMidlist[2], CircleMoveMidlist[3]);
                    break;
                default:
                    break;

            }

            if (move_modle == 1)
            { }


        }
        #region   //点击圆弧插补运动按钮
        private void btn_CircularMotion_MouseDown(object sender, MouseEventArgs e)
        {
            btn_CircularMotion.BackColor = Color.Green;
            move_modle = 2;
        }

        private void btn_CircularMotion_MouseUp(object sender, MouseEventArgs e)        //圆弧插补运动
        {
            btn_CircularMotion.BackColor = Color.Gainsboro;
            RunMove();
        }
        #endregion
        private void btn_Stop_Click(object sender, EventArgs e)
        {
            if (btn_Stop.Text == "急停")
            {

                zmcaux.ZAux_Direct_Rapidstop(g_handle, 0);
                btn_Stop.Text = "解除急停";
                label_state.Text = "运动状态：急停中";
                label_state.ForeColor = Color.Red;
                //   MessageBox.Show("急停报警！");
            }
            else if (btn_Stop.Text == "解除急停")
            {
                btn_Stop.Text = "急停";
                label_state.Text = "运动状态： 停止中";
                label_state.ForeColor = Color.Black;
            }
        }



        private void btn_StopMotion_MouseDown(object sender, MouseEventArgs e)
        {
            zmcaux.ZAux_Direct_Single_Cancel(g_handle, 0, 2);
            btn_StopMotion.BackColor = Color.Yellow;
        }

        private void btn_StopMotion_MouseUp(object sender, MouseEventArgs e)
        {
            btn_StopMotion.BackColor = Color.Gainsboro;
        }
        #region 点击直线运动按钮
        private void btn_linerMotion_MouseDown(object sender, MouseEventArgs e)
        {
            btn_linerMotion.BackColor = Color.Green;
            move_modle = 1;
        }

        private void btn_linerMotion_MouseUp(object sender, MouseEventArgs e)
        {
            btn_linerMotion.BackColor = Color.Gainsboro;
            RunMove();
        }

        #endregion

        private void tabpage4_Click(object sender, EventArgs e)
        {

        }

        public static void DelayTime(int _delaytime)
        {
            Thread.Sleep(_delaytime);
        }


        /// <summary>
        /// 点击设置键盘，保持轴参数
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_SetAxisParameter_MouseDown(object sender, MouseEventArgs e)
        {
            btn_SetAxisParameter.BackColor = Color.Green;

        }

        private void btn_SetAxisParameter_MouseUp(object sender, MouseEventArgs e)  //点击设置设置轴参数
        {
            btn_SetAxisParameter.BackColor = Color.Gainsboro;

            Initialization_Axix(nAxis);

        }



        #region 坐标的更新读取与移动到目标点
        public void pos_Upate()  //读取当前轴坐标，并填入到Lab中；
        {


            //Y轴坐标轴0
            zmcaux.ZAux_Direct_GetDpos(g_handle, 0, ref position[0]);
            lab_YPos.Text = "Y坐标:  " + position[0].ToString();


            //X轴坐标轴1
            zmcaux.ZAux_Direct_GetDpos(g_handle, 1, ref position[1]);
            lab_XPos.Text = "X坐标:  " + position[1].ToString();

            //Z轴坐标轴2
            zmcaux.ZAux_Direct_GetDpos(g_handle, 2, ref position[2]);
            lab_ZPos.Text = "Z坐标:  " + position[2].ToString();

        }
        public void UpdateCoordinate(decimal X_Value, decimal Y_Value)  //更新坐标的方法
        {
            X_Value = Convert.ToDecimal(position[1]);     //怎么给输入的形参赋值？？？
            Y_Value = Convert.ToDecimal(position[0]);
        }


        //移动到目标点的方法
        public void MoveToTargetPosition(decimal X_PointValue, decimal Y_PointValue)
        {
            int _axle = AxisList[0]; //主轴是轴0--Y横向
            int[] _piAxislist = { 0, 1 }; //移动带目标点用的轴列表
            float[] _poslist = { Convert.ToSingle(X_PointValue), Convert.ToSingle(Y_PointValue) }; //转化成插补坐标

            zmcaux.ZAux_Direct_SetSpeed(g_handle, _axle, Convert.ToSingle(DryRunAxis_Speed.Value));  //设置插补速度，设置在主轴上

            zmcaux.ZAux_Direct_SetAccel(g_handle, _axle, Convert.ToSingle(DryRunAxis_Accel.Value));  //设置插补加速度

            zmcaux.ZAux_Direct_MoveAbs(g_handle, 2, _piAxislist, _poslist);  //绝对直线插补运动到目标位置
        }

        //更新直线路径LineXY0起点的位置
        private void btn_UpdateLinePosXY0_Click(object sender, EventArgs e)
        {
            LinePos_X0StartPoint.Value = Convert.ToDecimal(position[1]);
            LinePos_Y0StartPoint.Value = Convert.ToDecimal(position[0]);

            //    UpdateCoordinate(LinePos_X0StartPoint.Value, LinePos_Y0StartPoint.Value);  //坐标X.Value，坐标Y.Value  

        }


        //移动到指定位置LineXY0
        private void btn_MoveToLinePosXY0_Click(object sender, EventArgs e)
        {
            MoveToTargetPosition(LinePos_X0StartPoint.Value, LinePos_Y0StartPoint.Value); //坐标X.Value，坐标Y.Value           
        }

        //更新直线路径LineXY1起点的位置
        private void btn_UpdateLinePosXY1_Click(object sender, EventArgs e)
        {
            LinePos_X1MidPoint.Value = Convert.ToDecimal(position[1]);
            LinePos_Y1MidPoint.Value = Convert.ToDecimal(position[0]);
            //UpdateCoordinate(LinePos_X1MidPoint.Value, LinePos_Y1MidPoint.Value);
        }

        //移动到指定位置LineXY1
        private void btn_MoveLinePosXY1_Click(object sender, EventArgs e)
        {
            MoveToTargetPosition(LinePos_X1MidPoint.Value, LinePos_Y1MidPoint.Value);
        }

        //更新直线路径LineXY2起点的位置
        private void btn_UpdateLinePosXY2_Click(object sender, EventArgs e)
        {
            LinePos_X2EndPoint.Value = Convert.ToDecimal(position[1]);
            LinePos_Y2EndPoint.Value = Convert.ToDecimal(position[0]);
            // UpdateCoordinate(LinePos_X2EndPoint.Value, LinePos_Y2EndPoint.Value);
        }

        //移动到指定位置LineXY2
        private void btn_MoveLinePosXY2_Click(object sender, EventArgs e)
        {
            MoveToTargetPosition(LinePos_X2EndPoint.Value, LinePos_Y2EndPoint.Value);
        }


        //更新直线路径LineZ0的位置
        private void btn_UpdateLinePosZ0_Click(object sender, EventArgs e)
        {

            LinePos_Z0Height.Value = Convert.ToDecimal(position[2]);
        }



        //下面是圆弧运动的所需的参数


        //更新直线路径CircleXY0起点的位置
        private void btn_UpdateCirclePosXY0_Click(object sender, EventArgs e)
        {
            CirclePos_X0StartPoint.Value = Convert.ToDecimal(position[1]);
            CirclePos_Y0StartPoint.Value = Convert.ToDecimal(position[0]);
            //    UpdateCoordinate(CirclePos_X0StartPoint.Value, CirclePos_Y0StartPoint.Value);
        }


        //移动到指定位置CircleXY0
        private void btn_MoveToCirclePosXY0_Click(object sender, EventArgs e)
        {
            MoveToTargetPosition(CirclePos_X0StartPoint.Value, CirclePos_Y0StartPoint.Value);
        }

        //更新直线路径CircleXY1中点的位置
        private void btn_UpdateCirclePosXY1_Click(object sender, EventArgs e)
        {
            CirclePos_X1MidPoint.Value = Convert.ToDecimal(position[1]);
            CirclePos_Y1MidPoint.Value = Convert.ToDecimal(position[0]);
            //UpdateCoordinate(CirclePos_X1MidPoint.Value, CirclePos_Y1MidPoint.Value);
        }

        //移动到指定位置CircleXY1
        private void btn_MoveToCirclePosXY1_Click(object sender, EventArgs e)
        {
            MoveToTargetPosition(CirclePos_X1MidPoint.Value, CirclePos_Y1MidPoint.Value);
        }

        //更新直线路径CircleXY2终点的位置
        private void btn_UpdateCirclePosXY2_Click(object sender, EventArgs e)
        {
            CirclePos_X2EndPoint.Value = Convert.ToDecimal(position[1]);
            CirclePos_Y2EndPoint.Value = Convert.ToDecimal(position[0]);
            // UpdateCoordinate(CirclePos_X2EndPoint.Value, CirclePos_Y2EndPoint.Value);
        }

        //移动到指定位置CircleXY2
        private void btn_MoveToCirclePosXY2_Click(object sender, EventArgs e)
        {

            MoveToTargetPosition(CirclePos_X2EndPoint.Value, CirclePos_Y2EndPoint.Value);
        }

        //更新圆弧路径LineZ0的位置
        private void btn_UpdateCirclePosZ0_Click(object sender, EventArgs e)
        {
            LinePos_Z0Height.Value = Convert.ToDecimal(position[2]);
        }

        #endregion



        //直线运动
        private void btn_linerMotion_Click_1(object sender, EventArgs e)
        {
            if (btn_linerMotion.Text == "直线运动")
            {
                btn_linerMotion.BackColor = Color.Green;
                btn_linerMotion.Text = "运动中";
                bool nextTomidpos = false;
                bool nextToEndpos = false;
                bool nextTocomplete = false;
                //Z轴如果不在0点，先把Z轴复位到原点
                zmcaux.ZAux_Direct_Single_Datum(g_handle, AxisList[2], 3);


                int _axle = AxisList[0];      //主轴是轴0--Y横向
                int[] _piAxislist = { 0, 1 }; //移动带目标点用的轴列表
                float[] poslist_start = { Convert.ToSingle(LinePos_X0StartPoint.Value), Convert.ToSingle(LinePos_Y0StartPoint.Value) }; //转化成插补坐标 起点
                float[] poslist_mid = { Convert.ToSingle(LinePos_X1MidPoint.Value), Convert.ToSingle(LinePos_Y1MidPoint.Value) }; //转化成插补坐标  中点
                float[] poslist_end = { Convert.ToSingle(LinePos_X2EndPoint.Value), Convert.ToSingle(LinePos_Y2EndPoint.Value) }; //转化成插补坐标  终点

                zmcaux.ZAux_Direct_SetSpeed(g_handle, _axle, Convert.ToSingle(WorkAxis_Speed.Value));  //设置插补速度，设置在主轴上
                zmcaux.ZAux_Direct_SetAccel(g_handle, _axle, Convert.ToSingle(WorkAxis_Accel.Value));  //设置插补加速度
                zmcaux.ZAux_Direct_SetDecel(g_handle, _axle, Convert.ToSingle(WorkAxis_decel.Value));   //设置插补减速度

                //先移动到起始点
                zmcaux.ZAux_Direct_MoveAbs(g_handle, 2, _piAxislist, poslist_start);  //绝对直线插补运动到目标位置
                if (position[0] == poslist_start[1] && position[1] == poslist_start[0])
                {
                    //Z轴下降
                    zmcaux.ZAux_Direct_Single_MoveAbs(g_handle, AxisList[2], Convert.ToSingle(LinePos_Z0Height.Value));
                    nextTomidpos = true;
                }

                //进行插补运动到中点
                if (position[2] == Convert.ToSingle(LinePos_Z0Height.Value) && nextTomidpos)
                {
                    zmcaux.ZAux_Direct_MoveAbs(g_handle, 2, _piAxislist, poslist_mid);
                    if (position[0] == poslist_mid[1] && position[1] == poslist_mid[0]) { nextToEndpos = true; }
                }

                //进行插补运动到终点
                if (nextToEndpos)
                {
                    zmcaux.ZAux_Direct_MoveAbs(g_handle, 2, _piAxislist, poslist_end);
                    nextToEndpos = false; nextTocomplete = true;
                }

                //完成运动
                if (nextTocomplete)
                {
                    if (position[0] == poslist_end[1] && position[0] == poslist_end[0])
                    {
                        btn_linerMotion.BackColor = Color.Gainsboro;
                        btn_linerMotion.Text = "直线运动";
                    }
                }



            }
        }

        /// <summary>
        /// 坐标清零
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SetZero_MouseDown(object sender, MouseEventArgs e)
        {
            //SetZero.BackColor = Color.Green;
            for (int i = 0; i < 3; i++)
            {
                zmcaux.ZAux_Direct_SetDpos(g_handle, AxisList[i], 0);
            }

        }

        private void SetZero_MouseUp(object sender, MouseEventArgs e)
        {
            //SetZero.BackColor = Color.Yellow;
            float reValue = 0;
            for (int i = 0; i < 3; i++)
            {
                zmcaux.ZAux_Direct_GetDpos(g_handle, AxisList[i], ref reValue);
            }
            if (reValue == 0)
            {
                MessageBox.Show("清零完成");
            }
        }

        //运行速度值改变事件
        private void WorkAxis_Speed_ValueChanged(object sender, EventArgs e)
        {
            zmcaux.ZAux_Direct_SetSpeed(g_handle, AxisList[0], Convert.ToSingle(WorkAxis_Speed.Value));  //设置插补速度，设置在主轴上
        }

        //放在定时器中，读取当前轴运动状态
        public void GetAxisStatusToLabel()
        {
            int[] runstate = new int[4];//运行状态
            float runspeed = 0;         //运行速度
            int Residual_buffer = 0;    //剩余缓冲
            int current_mark = 0;       //当前Move_Mark

            zmcaux.ZAux_Direct_GetSpeed(g_handle, AxisList[0], ref runspeed); //读取速度
            label_vspeed.Text = Convert.ToString(runspeed);

            for (int i = 0; i < 3; i++)
            {
                zmcaux.ZAux_Direct_GetIfIdle(g_handle, AxisList[i], ref runstate[i]);
            }
            if (runstate[0] == 0 && runstate[1] == 0 && runstate[2] == 0)
            {
                label_state.Text = "运行状态： 运行";
            }
            else
            {
                label_state.Text = "运行状态： 停止";
            }



            //判断存放直线的剩余缓冲 ，ZAux_Direct_GetRemain_Buffer判断的空间圆弧的缓冲，也是占缓冲最大的运动
            zmcaux.ZAux_Direct_GetRemain_LineBuffer(g_handle, 0, ref Residual_buffer);
            label_buff.Text = "剩余缓冲: " + "Residual_buffer";
            //判断当前运动到第几条运动，
            zmcaux.ZAux_Direct_GetMoveCurmark(g_handle, 0, ref current_mark);
            label_mark.Text = "当前MARK：" + "current_mark";
        }

        private void tabControl1_SelectedIndexChanged(object sender, EventArgs e)
        {



        }
    }
}

